#include "gtsort.h"

#include <stdlib.h>
#include <string.h>

errno_t swap(
	void *restrict left, \
	void *restrict right, \
	size_t size, \
	void **context)
{
	if (left == NULL \
		|| right == NULL || size == 0)
	{
		if (context)
		{
			free(*context);
			*context = NULL;
		}
		return 0;
	}
	if (left == right)
		return 0;

	void *buffer;
	if (context)
	{
		void *temp = *context;
		if (temp && *(size_t*)temp < size)
		{
			free(temp);
			*context = temp = NULL;
		}
		if (temp == NULL)
		{
			*context = temp = malloc(sizeof(size_t) + size);
			if (temp == NULL)
				return ERROR_MEM_ALLOC;
			*(size_t*)temp = size;
		}
		buffer = (void*)((size_t)temp + sizeof(size_t));
	}
	else
		buffer = malloc(size);

	memcpy(buffer, left, size);
	memcpy(left, right, size);
	memcpy(right, buffer, size);

	if (context == NULL)
		free(buffer);
	return 0;
}
